package com.silence.gmall.generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author silence
 * @Email 792245022@qq.com
 * @Date 2025-06-10 15:59
 * @Description MyBatis-Plus 代码生成器
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MyBatisPlusGenerator {

    // 数据库连接配置
    static String url = "jdbc:mysql://192.168.200.100:3306/gmall_product" +
            "?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
    static String username = "root";
    static String password = "root";

    // 项目根路径
    // String projectPath = System.getProperty("user.dir");
    static String projectPath = "E:\\Workspaces\\Workspace_Item\\2025\\gmall-parent\\service\\service-product";

    /**
     * 一次性生成Repository和Service层的代码
     *
     * @param moduleName  模块名称 (如: coupon, product 等)
     * @param tablePrefix 表前缀 (如: sms_, pms_ 等)
     * @param tables      要生成的表名 (如: sms_coupon, pms_product 等)
     */
    public static void generate(String moduleName, String tablePrefix, String... tables) {
        log.info("=== 开始生成Repository和Service双层代码 ===");

        // 1. 生成Repository层
        generateRepository(tablePrefix, tables);

        // 2. 生成Service层
        generateService(moduleName, tablePrefix, tables);

        log.info("=== Repository和Service双层代码生成完成 ===");
    }

    /**
     * 代码生成的方法
     *
     * @param tablePrefix 表前缀 (如: sms_, pms_ 等)
     * @param tables      要生成的表名 (如: sms_coupon, pms_product 等)
     */
    public static void generateRepository(String tablePrefix, String... tables) {

        // 各个文件的输出路径
        String javaOutputDir = projectPath + "/src/main/java";
        String mapperXmlOutputDir = projectPath + "/src/main/resources/mapper";

        // 设置不同文件的输出路径
        Map<OutputFile, String> pathInfo = new EnumMap<>(OutputFile.class);
        pathInfo.put(OutputFile.xml, mapperXmlOutputDir);

        // 使用 FastAutoGenerator 构建代码生成器
        FastAutoGenerator.create(url, username, password)
                // 全局配置
                .globalConfig(builder ->
                        builder.author("silence") // 设置作者
                                .outputDir(javaOutputDir) // 指定输出目录
                                .commentDate("yyyy-MM-dd HH:mm:ss") // 设置注释日期格式
                )
                // 包配置
                .packageConfig(builder ->
                        builder.parent("com.silence.gmall.product.domain") // 设置父包名
                                .moduleName("") // 设置父包模块名
                                .entity("entity") // entity 包名
                                .service("repository") // repository 包名 (原 service)
                                .serviceImpl("repository.impl") // repository 实现包名 (原 service.impl)
                                .mapper("mapper") // mapper 包名
                                .xml("mapper") // mapper xml 包名
                                .pathInfo(pathInfo) // 设置路径信息
                )
                // 策略配置
                .strategyConfig(builder ->
                        builder.addInclude(tables) // 设置需要生成的表名
                                .addTablePrefix(tablePrefix) // 设置过滤表前缀
                                // Entity 策略配置
                                .entityBuilder()
                                .enableFileOverride() // 覆盖
                                .enableLombok() // 开启 lombok
                                .enableTableFieldAnnotation() // 开启生成实体时生成字段注解
                                .enableRemoveIsPrefix() // 开启 Boolean 类型字段移除 is 前缀
                                .enableActiveRecord() // 开启 ActiveRecord 模式
                                .formatFileName("%s") // 实体名称格式
                                // Mapper 策略配置
                                .mapperBuilder()
                                .enableFileOverride() // 覆盖
                                .enableBaseResultMap() // 启用 BaseResultMap 生成
                                .enableBaseColumnList() // 启用 BaseColumnList 生成
                                .formatMapperFileName("%sMapper") // Mapper 文件名称格式
                                .formatXmlFileName("%sMapper") // XML 文件名称格式
                                // Service 策略配置 (修改为 Repository)
                                .serviceBuilder()
                                .enableFileOverride() // 覆盖
                                .formatServiceFileName("%sRepository") // Repository 接口名称格式
                                .formatServiceImplFileName("%sRepositoryImpl") // Repository 实现类名称格式
                                // Controller 策略配置
                                .controllerBuilder()
                                .disable()
                                .enableFileOverride() // 覆盖
                )
                // 模板配置
                .strategyConfig(builder ->
                        builder.entityBuilder()
                                .javaTemplate("/templates/entity.java") // 设置实体类模板
                                .mapperBuilder()
                                .mapperTemplate("/templates/mapper.java") // 设置 Mapper 模板
                                .mapperXmlTemplate("/templates/mapper.xml") // 设置 Mapper XML 模板
                                .serviceBuilder()
                                .serviceTemplate("/templates/repository.java") // 设置 Service 模板
                                .serviceImplTemplate("/templates/repositoryImpl.java") // 设置 ServiceImpl 模板
                                .build()
                )
                // 使用 Freemarker 引擎模板，默认的是 Velocity 引擎模板
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }

    /**
     * 生成Service层
     */
    private static void generateService(String moduleName, String tablePrefix, String... tables) {
        // 各个文件的输出路径
        String javaOutputDir = projectPath + "/src/main/java";
        String mapperXmlOutputDir = projectPath + "/src/main/resources/mapper";

        // 设置不同文件的输出路径
        Map<OutputFile, String> pathInfo = new EnumMap<>(OutputFile.class);
        pathInfo.put(OutputFile.xml, mapperXmlOutputDir);

        // 使用 FastAutoGenerator 构建代码生成器
        FastAutoGenerator.create(url, username, password)
                // 全局配置
                .globalConfig(builder ->
                        builder.author("silence") // 设置作者
                                .outputDir(javaOutputDir) // 指定输出目录
                                .commentDate("yyyy-MM-dd HH:mm:ss") // 设置注释日期格式
                )
                // 包配置
                .packageConfig(builder ->
                        builder.parent("com.silence.gmall.product") // 设置父包名
                                .moduleName("") // 设置父包模块名
                                .entity("domain") // entity 包名
                                .service("service") // service 包名
                                .serviceImpl("service.impl") // service 实现包名
                                .mapper("mapper") // mapper 包名
                                .xml("mapper") // mapper xml 包名
                                .pathInfo(pathInfo) // 设置路径信息
                )
                // 策略配置
                .strategyConfig(builder ->
                        builder.addInclude(tables) // 设置需要生成的表名
                                .addTablePrefix(tablePrefix) // 设置过滤表前缀
                                // Entity 策略配置
                                .entityBuilder()
                                .disable()
                                // Mapper 策略配置
                                .mapperBuilder()
                                .disable()
                                // Service 策略配置
                                .serviceBuilder()
                                .enableFileOverride() // 覆盖
                                .formatServiceFileName("%sService") // Service 接口名称格式
                                .formatServiceImplFileName("%sServiceImpl") // Service 实现类名称格式
                                // Controller 策略配置
                                .controllerBuilder()
                                .enableFileOverride() // 覆盖
                )
                // 模板配置
                .strategyConfig(builder ->
                        builder.entityBuilder()
                                .serviceBuilder()
                                .serviceTemplate("/templates/service.java") // 设置 Service 模板
                                .serviceImplTemplate("/templates/serviceImpl.java") // 设置 ServiceImpl 模板
                                .build()
                )
                .injectionConfig(injectConfig -> {
                    Map<String,Object> customMap = new HashMap<>();
                    customMap.put("urlRoot", moduleName);
                    injectConfig.customMap(customMap); //注入自定义属性
                })
                // 使用 Freemarker 引擎模板，默认的是 Velocity 引擎模板
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }
}